/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {
  $createTableCellNode,
  $createTableNode,
  $createTableRowNode,
  $isTableNode,
  TableCellHeaderStates,
  TableCellNode,
  TableNode,
  TableRowNode,
} from '@lexical/table';
import {
  $createParagraphNode,
  $createTextNode,
  $getSelection,
  $insertNodes,
  $isRangeSelection,
  COMMAND_PRIORITY_HIGH,
  PASTE_COMMAND,
} from 'lexical';
import {useEffect} from 'react';

/**
 * 将各种宽度单位转换为像素值
 */
function convertToPixels(width: string, referenceElement?: HTMLElement): number {
  const match = width.match(/^(\d+(?:\.\d+)?)(.*)$/);
  if (!match) {
    return 92; // 默认宽度
  }

  const value = parseFloat(match[1]);
  const unit = match[2].toLowerCase().trim() || 'px';

  switch (unit) {
    case 'px':
      return value;
    case '%':
      // 对于百分比，我们需要一个参考宽度
      // 假设容器宽度为 800px（可以根据实际需要调整）
      const containerWidth = referenceElement?.offsetWidth || 800;
      return (value / 100) * containerWidth;
    case 'em':
    case 'rem':
      // 假设 1em = 16px（可以根据实际需要调整）
      return value * 16;
    case 'pt':
      // 1pt = 4/3 px
      return value * (4 / 3);
    case 'in':
      // 1in = 96px
      return value * 96;
    case 'cm':
      // 1cm = 37.8px
      return value * 37.8;
    case 'mm':
      // 1mm = 3.78px
      return value * 3.78;
    default:
      return value; // 假设是像素值
  }
}

/**
 * 解析所有 HTML 表格并提取列宽信息
 */
function parseAllHTMLTables(htmlString: string): Array<{
  tableData: Array<Array<{content: string; isHeader: boolean}>>;
  colWidths: Array<number> | null;
  originalHTML: string;
}> {
  try {
    const parser = new DOMParser();
    const doc = parser.parseFromString(htmlString, 'text/html');
    const tables = doc.querySelectorAll('table');
    
    if (tables.length === 0) {
      return [];
    }

    const results: Array<{
      tableData: Array<Array<{content: string; isHeader: boolean}>>;
      colWidths: Array<number> | null;
      originalHTML: string;
    }> = [];

    tables.forEach((table) => {
      const tableResult = parseSingleTable(table);
      if (tableResult) {
        results.push({
          ...tableResult,
          originalHTML: table.outerHTML
        });
      }
    });

    return results;
  } catch (error) {
    console.error('Error parsing HTML tables:', error);
    return [];
  }
}

/**
 * 解析单个 HTML 表格并提取列宽信息
 */
function parseSingleTable(table: Element): {
  tableData: Array<Array<{content: string; isHeader: boolean}>>;
  colWidths: Array<number> | null;
} | null {
  try {
    const rows: Array<Array<{content: string; isHeader: boolean}>> = [];
    let colWidths: Array<number> | null = null;
    
    // 首先检查表格本身是否有宽度信息
    const tableWidth = (table as HTMLElement).style.width || table.getAttribute('width');
    
    // 检查是否有 colgroup 或 col 元素定义列宽
    const colgroup = table.querySelector('colgroup');
    if (colgroup) {
      const cols = colgroup.querySelectorAll('col');
      if (cols.length > 0) {
        const widths: Array<number> = [];
        let hasCustomWidths = false;
        
        Array.from(cols).forEach(col => {
          const width = (col as HTMLElement).style.width || col.getAttribute('width');
          if (width && width !== 'auto') {
            const pixelWidth = Math.max(convertToPixels(width, table as HTMLElement), 92);
            widths.push(pixelWidth);
            hasCustomWidths = true;
          } else {
            widths.push(92);
          }
        });
        
        if (hasCustomWidths) {
          colWidths = widths;
        }
      }
    }

    // 如果没有 colgroup，尝试从所有行的 th/td 元素中提取宽度
    if (!colWidths) {
      const allRows = table.querySelectorAll('tr');
      let maxCellsInRow = 0;
      let bestWidths: number[] = [];
      let maxCustomWidths = 0;
      
      // 检查每一行，找到最有用的宽度信息
      allRows.forEach((row, rowIndex) => {
        const cells = row.querySelectorAll('th, td');
        const cellCount = cells.length;
        
        if (cellCount > 0) {
          const widths: Array<number> = [];
          let customWidthCount = 0;
          
          cells.forEach((cell, cellIndex) => {
            const cellElement = cell as HTMLElement;
            const styleWidth = cellElement.style.width;
            const attrWidth = cellElement.getAttribute('width');
            
            let width = styleWidth || attrWidth;
            if (width && width !== 'auto' && width !== '0' && width !== '') {
              const pixelWidth = Math.max(convertToPixels(width, table as HTMLElement), 92);
              widths.push(pixelWidth);
              customWidthCount++;
            } else {
              widths.push(92);
            }
          });
          
          // 选择有最多自定义宽度的行
          if (customWidthCount > maxCustomWidths || 
              (customWidthCount === maxCustomWidths && cellCount > maxCellsInRow)) {
            maxCustomWidths = customWidthCount;
            maxCellsInRow = cellCount;
            bestWidths = widths;
          }
        }
      });
      
      if (bestWidths.length > 0 && maxCustomWidths > 0) {
        colWidths = bestWidths;
      }
    }

    // 解析表格内容
    const tableRows = table.querySelectorAll('tr');
    tableRows.forEach(row => {
      const cells = row.querySelectorAll('th, td');
      const rowData: Array<{content: string; isHeader: boolean}> = [];
      
      cells.forEach(cell => {
        const isHeader = cell.tagName.toLowerCase() === 'th';
        const content = cell.textContent?.trim() || '';
        rowData.push({content, isHeader});
      });
      
      if (rowData.length > 0) {
        rows.push(rowData);
      }
    });

    return {
      tableData: rows,
      colWidths
    };
  } catch (error) {
    console.error('Error parsing single table:', error);
    return null;
  }
}

/**
 * 创建带有自定义列宽的表格节点
 */
function createTableWithColWidths(
  tableData: Array<Array<{content: string; isHeader: boolean}>>,
  colWidths: Array<number> | null
): TableNode {
  const table = $createTableNode();
  
  // 创建表格行和单元格
  tableData.forEach(rowData => {
    const tableRow = $createTableRowNode();
    
    rowData.forEach(cellData => {
      const headerState = cellData.isHeader 
        ? TableCellHeaderStates.ROW 
        : TableCellHeaderStates.NO_STATUS;
      
      const tableCell = $createTableCellNode(headerState);
      
      if (cellData.content.trim()) {
        const paragraph = $createParagraphNode();
        paragraph.append($createTextNode(cellData.content.trim()));
        tableCell.append(paragraph);
      } else {
        // 即使内容为空也要添加一个空段落，否则单元格可能不可编辑
        const paragraph = $createParagraphNode();
        tableCell.append(paragraph);
      }
      
      tableRow.append(tableCell);
    });
    
    table.append(tableRow);
  });

  // 设置列宽 - 必须在表格结构创建完成后设置
  if (colWidths && colWidths.length > 0) {
    // 确保列宽数组长度与实际列数匹配
    const maxCols = Math.max(...tableData.map(row => row.length));
    const adjustedColWidths = [...colWidths];
    
    // 如果列宽数组不够长，用默认值填充
    while (adjustedColWidths.length < maxCols) {
      adjustedColWidths.push(92);
    }
    
    // 如果列宽数组太长，截断
    if (adjustedColWidths.length > maxCols) {
      adjustedColWidths.splice(maxCols);
    }
    
    table.setColWidths(adjustedColWidths);
  }

  return table;
}



/**
 * 检查 HTML 内容是否只包含表格
 */
function isTableOnlyContent(htmlString: string): boolean {
  try {
    const parser = new DOMParser();
    const doc = parser.parseFromString(htmlString, 'text/html');
    const body = doc.body;
    
    const tables = body.querySelectorAll('table');
    if (tables.length === 0) {
      return false;
    }
    
    // 获取所有文本内容和表格内容
    const allText = (body.textContent || '').replace(/\s+/g, ' ').trim();
    let tableText = '';
    tables.forEach(table => {
      tableText += (table.textContent || '').replace(/\s+/g, ' ').trim() + ' ';
    });
    tableText = tableText.trim();
    
    // 简单判断：如果所有文本都来自表格，则认为是纯表格内容
    return allText === tableText;
  } catch (error) {
    console.error('Error checking table-only content:', error);
    return false;
  }
}

export default function EnhancedTablePastePlugin(): null {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    return editor.registerCommand(
      PASTE_COMMAND,
      (event: ClipboardEvent) => {
        const clipboardData = event.clipboardData;
        if (!clipboardData) {
          return false;
        }

        const htmlData = clipboardData.getData('text/html');
        
        // 检查是否包含表格
        if (htmlData && htmlData.includes('<table')) {
          const tablesInfo = parseAllHTMLTables(htmlData);
          
          if (tablesInfo.length > 0) {
            // 检查是否有任何表格有自定义列宽
            const hasAnyCustomWidths = tablesInfo.some(tableInfo => 
              tableInfo.colWidths && tableInfo.colWidths.some(width => width !== 92 && width > 0)
            );
            
            // 检查是否是纯表格内容
            const isTableOnly = isTableOnlyContent(htmlData);
            
            // 对于纯表格内容（单个或多个），直接处理
            if (isTableOnly) {
              event.preventDefault();
              
              editor.update(() => {
                const selection = $getSelection();
                
                if ($isRangeSelection(selection)) {
                  const nodesToInsert: TableNode[] = [];
                  
                  tablesInfo.forEach((tableInfo) => {
                    const table = createTableWithColWidths(
                      tableInfo.tableData, 
                      tableInfo.colWidths
                    );
                    nodesToInsert.push(table);
                  });
                  
                  $insertNodes(nodesToInsert);
                }
              });
              
              return true;
            }
            
            // 对于混合内容，使用后处理策略
            if (hasAnyCustomWidths) {
              // 存储所有表格的宽度信息
              const allTableWidths = tablesInfo.map(t => t.colWidths).filter(w => w !== null);
              
              // 延迟应用宽度设置
              setTimeout(() => {
                editor.update(() => {
                  editor.getEditorState().read(() => {
                    const nodeMap = editor.getEditorState()._nodeMap;
                    const tableNodes: TableNode[] = [];
                    
                    // 收集所有表格节点
                    for (const [key, node] of nodeMap) {
                      if ($isTableNode(node)) {
                        tableNodes.push(node as TableNode);
                      }
                    }
                    
                    // 应用宽度到对应的表格
                    if (tableNodes.length >= allTableWidths.length) {
                      // 从最新的表格开始应用（假设是刚插入的）
                      const startIndex = tableNodes.length - allTableWidths.length;
                      
                      allTableWidths.forEach((widths, index) => {
                        if (widths && widths.length > 0) {
                          const tableNode = tableNodes[startIndex + index];
                          
                          editor.update(() => {
                            tableNode.setColWidths(widths);
                          });
                        }
                      });
                    }
                  });
                });
              }, 300);
            }
          }
        }

        // 对于其他情况（包含文本和表格的复合内容），让默认粘贴处理器处理
        return false;
      },
      COMMAND_PRIORITY_HIGH,
    );
  }, [editor]);

  return null;
}
